import React, { Component } from 'react'
import { Checkbox, Button, message, Popover, Input, Space } from 'antd'
import { DownOutlined, CloseCircleOutlined, InfoCircleOutlined, UserOutlined, LockOutlined } from '@ant-design/icons'
import { connect } from 'react-redux'
import moment from 'moment'
import FreeScrollBar from 'react-free-scrollbar'
import { setSendTime, setLoginMobile, setToken, setUserInfo, setUncompleteMessage, setUncompleteMessageNum, clearWindow } from '../redux/actions'
import telZone from '../assets/js/telZone'
import style from './Login.module.less'
import { $post } from '../assets/js/request'
import { appName, companyName } from '../assets/js/config'
import logo from '@img/logo.png'
import { version } from 'process'
import { compress, decompress } from '@src/assets/js/tool'

const { Search } = Input
const zoneTelList = []
telZone.forEach(l => zoneTelList.push(l.tel))

class Login extends Component {
  state = {
    zoneNum: '86',
    username: '',
    mobile: '',
    verification: '',
    password: '',
    notice_username: '',
    notice_mobile: '',
    notice_verification: '',
    notice_password: '',
    agree: true,
    loading: false,
    isLoginByPassword: true, // 是否为通过密码登录
    loopTime: 0, // 倒计时
    zoneTelVisible: false, // 是否显示国际区号列表
    zoneSearchStr: '' // 区号搜索文本
  }

  // 登录按钮是否禁用
  isBtnDisable () {
    const { username, mobile, zoneNum, verification, password, agree, isLoginByPassword } = this.state
    if (isLoginByPassword) {
      return !username || !password || !agree
    }
    return !mobile || !zoneNum || !verification || !agree
  }

  // 获取过滤后的区号
  getFilterTelZone () {
    return telZone.filter(li => {
      const en = li.en.toLocaleLowerCase()
      const s = this.state.zoneSearchStr.toLocaleLowerCase()
      const isTel = li.tel.indexOf(s) !== -1
      const isCn = li.name.indexOf(s) !== -1
      const isEn = en.indexOf(s) !== -1
      return isTel || isCn || isEn
    })
  }

  // 验证手机号格式
  validateMobile () {
    const { mobile } = this.state
    if (!mobile) {
      this.setState({
        notice_mobile: '手机号不能为空'
      })
      return false
    }
    if (!/^1[3-9]\d{9}$/.test(this.state.mobile)) {
      this.setState({
        notice_mobile: '手机号格式不正确'
      })
      return false
    }
    this.setState({
      notice_mobile: ''
    })
    return true
  }

  // 验证账号
  validateUsername () {
    const { username } = this.state
    if (!username) {
      this.setState({
        notice_username: '账号不能为空'
      })
      return false
    }
    return true
  }

  // 验证国际区号
  validateZoneTel () {
    const { zoneNum } = this.state
    if (!zoneNum) {
      this.setState({
        notice_mobile: '国际区号不能为空'
      })
      return false
    }
    if (zoneTelList.indexOf(zoneNum) === -1) {
      this.setState({
        notice_mobile: '国际区号不存在'
      })
      return false
    }
    this.setState({
      notice_mobile: ''
    })
    return true
  }

  // 验证验证码
  validateVerification () {
    const { verification } = this.state
    if (!verification) {
      this.setState({
        notice_verification: '验证码不能为空'
      })
      return false
    }
    if (!/^\d{4}$/.test(verification)) {
      this.setState({
        notice_verification: '验证码格式不正确'
      })
      return false
    }
    this.setState({
      notice_verification: ''
    })
    return true
  }

  // 验证密码
  validatePassword () {
    const { password } = this.state
    if (!password) {
      this.setState({
        notice_password: '密码不能为空'
      })
      return false
    }
    this.setState({
      notice_password: ''
    })
    return true
  }

  // 验证是否勾选同意协议
  validateAgree () {
    if (!this.state.agree) {
      message.warning('请勾选同意使用协议')
      return false
    }
    return true
  }

  // 设置倒计时
  setLoopTime () {
    const { sendTime } = this.props
    if (!sendTime) {
      return false
    }
    const time = 60 - Math.ceil((moment() - sendTime) / 1000)
    this.setState({
      loopTime: time > 0 ? time : 0
    })
  }

  // 倒计时
  loop () {
    this.setLoopTime()
    if (this.state.loopTime > 0) {
      this.timer = setTimeout(() => {
        this.loop()
      }, 1000)
    }
  }

  // 发送验证码
  sendSMS () {
    if (!this.validateZoneTel() || !this.validateMobile()) {
      return false
    }
    this.sendSMSRequest()
  }

  // 设置国际区号
  setZoneTel (tel) {
    this.setState({
      zoneNum: tel,
      zoneTelVisible: false
    })
  }

  // 登录
  login () {
    if (this.state.loading) {
      return undefined
    }
    this.setState({
      loading: true
    })
    if (this.state.isLoginByPassword) {
      this.loginByPassword()
    } else {
      this.loginByVerification()
    }
  }

  // 使用手机号验证码登录
  loginByVerification () {
    if (!this.validateZoneTel() || !this.validateMobile() || !this.validateVerification() || !this.validateAgree()) {
      return false
    }
    const hide = message.loading('登录中', 120)
    $post('/api/common/mobile_login', {
      zoneNum: this.state.zoneNum,
      mobile: compress(this.state.mobile),
      verification: this.state.verification
    }).then(res => {
      hide()
      if (res.status !== 1) {
        this.setState({
          loading: false
        })
        return message.error(res.message)
      }
      const { userInfo, token } = res.data
      this.props.setUncompleteMessage([])
      this.props.setUncompleteMessageNum(0)
      this.props.clearWindow()
      if (typeof userInfo.mobile === 'string' && userInfo.mobile.length) {
        userInfo.mobile = decompress(userInfo.mobile)
      }
      this.props.setUserInfo(userInfo)
      this.props.setToken(token)
      message.success('登录成功', 2, () => {
        this.props.history.push('/')
        this.setState({
          loading: false
        })
      })
    }, () => {
      hide()
      this.setState({
        loading: false
      })
    })
  }

  // 使用账号密码登录
  loginByPassword () {
    if (!this.validateUsername() || !this.validatePassword() || !this.validateAgree()) {
      return false
    }
    const hide = message.loading('登录中', 120)
    $post('/api/common/user_login', {
      username: this.state.username.trim(),
      password: this.state.password.trim()
    }).then(res => {
      hide()
      if (res.status !== 1) {
        this.setState({
          loading: false
        })
        return message.error(res.message)
      }
      const { userInfo, token } = res.data
      this.props.setUncompleteMessage([])
      this.props.setUncompleteMessageNum(0)
      this.props.clearWindow()
      if (typeof userInfo.mobile === 'string' && userInfo.mobile.length) {
        userInfo.mobile = decompress(userInfo.mobile)
      }
      this.props.setUserInfo(userInfo)
      this.props.setToken(token)
      message.success('登录成功', 2, () => {
        this.props.history.push('/')
        this.setState({
          loading: false
        })
      })
    }, () => {
      hide()
      this.setState({
        loading: false
      })
    })
  }

  // 发送短信请求
  sendSMSRequest () {
    if (!this.validateMobile()) {
      return false
    }
    const hide = message.loading('发送中', 120)
    $post('/api/common/sms', {
      mobile: compress(this.state.mobile),
      template_code: 'SMS_182920835'
    }).then(res => {
      hide()
      if (res.status === 1) {
        message.success(res.message, 2)
        this.props.setLoginMobile(this.state.mobile)
        this.props.setSendTime(moment().valueOf())
        setTimeout(() => {
          this.loop()
        }, 120)
      } else {
        message.error(res.message, 2)
      }
    }).catch(() => {
      hide()
    })
  }

  // 回车触发提交
  enterHandle (e) {
    const key = e.keyCode || e.which || e.charCode
    if (key === 13) {
      this.login()
    }
  }

  componentDidMount () {
    this.setState({
      mobile: this.props.mobile
    })
    this.setLoopTime()
    setTimeout(() => {
      this.loop()
    }, 120)
  }

  componentWillUnmount () {
    this.timer && clearTimeout(this.timer)
  }

  // 渲染清除按钮
  renderClearBtn (type) {
    const val = this.state[type] || ''
    if (val.length) {
      return (
        <div className={style['input-clear-btn']}>
          <CloseCircleOutlined onClick={() => this.setState({ [type]: '' })} />
        </div>
      )
    }
  }

  // 渲染提示
  renderNotice (type) {
    const val = this.state[`notice_${type}`] || ''
    if (val.length) {
      return (
        <div className={style['input-notice']}>
          <InfoCircleOutlined />
          <span className={style['input-notice-text']}>{val}</span>
        </div>
      )
    }
  }

  // 渲染发送短信按钮
  renderSendBtn () {
    const { loopTime } = this.state
    // const now = moment.now()
    if (loopTime) {
      return (
        <div className={`${style['sms-btn']} ${style.disable}`}>
          <span className={style['sms-time-text']}>{loopTime}秒</span>
        </div>
      )
    } else {
      return (
        <div className={style['sms-btn']}>
          <div className={style['sms-btn-text']} onClick={() => this.sendSMS()}>
            <span>发送验证码</span>
          </div>
        </div>
      )
    }
  }

  // 渲染国际区号列表
  getZoneList () {
    return (
      <div className={style['zone-tel-block']}>
        <Search
          placeholder='请输入区号、中文名或者英文名'
          onInput={v => this.setState({ zoneSearchStr: v.target.value })}
          onChange={v => this.setState({ zoneSearchStr: v.target.value })}
          allowClear
          className={style['zone-tel-search']}
        />
        <ul className={style['zone-list']}>
          <FreeScrollBar className='mock'>
            {this.getFilterTelZone().map((li, i) => {
              return (
                <li key={i} onClick={() => this.setZoneTel(li.tel)}>
                  <span className={style['zone-tel']}>+{li.tel}</span>
                  <span className={style['zone-cn']}>{li.name}</span>
                  <span className={style['zone-en']}>({li.en})</span>
                </li>
              )
            })}
          </FreeScrollBar>
        </ul>
      </div>
    )
  }

  // 根据登录方式渲染输入框
  renderLoginTypeInput () {
    if (this.state.isLoginByPassword) {
      return (
        <div>
          <div className={style['password-block']}>
            <span className={style['password-icon']}><UserOutlined /></span>
            <input placeholder='请输入账号' value={this.state.username} onChange={v => this.setState({ username: v.target.value })} autoComplete='off' onKeyPress={e => this.enterHandle(e)} />
            {this.renderClearBtn('username')}
          </div>

          <div className={style['white-space']}>
            {this.renderNotice('username')}
          </div>

          <div className={style['password-block']}>
            <span className={style['password-icon']}><LockOutlined /></span>
            <input type='password' placeholder='请输入密码' value={this.state.password} autoComplete='off' onChange={v => this.setState({ password: v.target.value })} onKeyPress={e => this.enterHandle(e)} />
            {this.renderClearBtn('password')}
          </div>
        </div>
      )
    }
    return (
      <div>
        <div className={style['mobile-block']}>
          <div className={style['zone-block']}>
            <input className={style['zone-input']} type='text' maxLength='5' value={`+${this.state.zoneNum}`} onChange={v => this.setState({ zoneNum: v.target.value.slice(1) })} onKeyPress={e => this.enterHandle(e)} />
            <Popover
              content={this.getZoneList()} trigger='click' visible={this.state.zoneTelVisible}
              onOpenChange={v => this.setState({ zoneTelVisible: v })}
            >
              <div className={style['zone-block-arrow']}>
                <DownOutlined />
              </div>
            </Popover>
          </div>
          <input className={style['mobile-input']} type='text' autoComplete='off' placeholder='请输入你的手机号码' maxLength='11' value={this.state.mobile} onChange={v => this.setState({ mobile: v.target.value })} onKeyPress={e => this.enterHandle(e)} />
          {this.renderClearBtn('mobile')}
        </div>
        <div className={style['white-space']}>
          {this.renderNotice('mobile')}
        </div>
        <div className={style['verification-block']}>
          <div className={style['verification-input']}>
            <input type='text' placeholder='请输入验证码' maxLength={4} autoComplete='off' value={this.state.verification} onChange={v => this.setState({ verification: v.target.value })} onKeyPress={e => this.enterHandle(e)} />
            {this.renderClearBtn('verification')}
          </div>
          {this.renderSendBtn()}
        </div>
      </div>
    )
  }

  // 渲染切换登录方式按钮
  renderToggleTypeBtn () {
    return (
      <span onClick={() => this.setState({ isLoginByPassword: !this.state.isLoginByPassword })}>
        {this.state.isLoginByPassword ? '手机验证码登录' : '账号密码登录'}
      </span>
    )
  }

  render () {
    return (
      <div className={style.login}>
        <div className={style['login-content']}>
          <div className={style['login-content__block']}>
            <div className={style['login-content__form']}>
              <div className={style['title-line']}>
                <img src={logo} className={style.logo} />
                <span className={style['title-line-text']}>{appName}</span>
              </div>
              {this.renderLoginTypeInput()}

              <div className={style['white-space']}>
                {this.renderNotice('verification')}
              </div>

              <div className={style['login-toggle-type']}>
                {this.renderToggleTypeBtn()}
              </div>

              <div className={style['protocol-block']}>
                <Checkbox checked={this.state.agree} onChange={v => this.setState({ agree: v })} className={style['protocol-checkbox']} />
                <span onClick={() => this.setState({ agree: !this.state.agree })}>
                  <span>我同意{companyName}使用我所提交的手机号用于快捷注册/登录。查看</span>
                  <span className={style['protocol-link']}>《用户服务协议》</span>
                  <span>及</span>
                  <span className={style['protocol-link']}>《隐私政策》</span>
                </span>
              </div>

              <div className={style['btn-line']}>
                <Button className={style['login-btn']} disabled={this.isBtnDisable()} type='primary' block onClick={() => this.login()}>登录</Button>
              </div>

            </div>
          </div>
        </div>
        <div className={style.foot}>
          <Space>
            {/* <span>{companyName}</span> */}
            <span>© 黑龙江省司法厅 版权所有</span>
            {/* <span>{companyUrl}</span> */}
            <span>{version}</span>
          </Space>
        </div>
      </div>
    )
  }
}

function mapStateToProps (state) {
  return {
    sendTime: state.basic.sendTime,
    mobile: state.basic.mobile
  }
}

function mapDispatchToProps (dispatch) {
  return {
    setSendTime: (i) => dispatch(setSendTime(i)),
    setLoginMobile: (i) => dispatch(setLoginMobile(i)),
    setToken: (i) => dispatch(setToken(i)),
    setUserInfo: (i) => dispatch(setUserInfo(i)),
    setUncompleteMessage: i => dispatch(setUncompleteMessage(i)),
    setUncompleteMessageNum: i => dispatch(setUncompleteMessageNum(i)),
    clearWindow: i => dispatch(clearWindow(i))
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(Login)
